package shell.command;

import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

import shell.Shell;

/**
 * Commande echo.
 * 
 * @version 1.0
 */
public class RunCommandImpl extends ShellCommandImpl {
    /**
     * Constructeur.
     * 
     * @param context
     *            Contexte d'exécution.
     */
    public RunCommandImpl(final ShellContext context) {
	super(context);
    }

    /**
     * @see shell.command.ShellCommand#getName().
     */
    public final String getName() {
	return "run";
    }

    /**
     * @see shell.command.ShellCommand#getUsage().
     */
    public final String getUsage() {
	return "run <package.ClassName> <args>";
    }

    /**
     * @see shell.command.ShellCommand#getShortDescription().
     */
    public final String getShortDescription() {
	return "Run a method";
    }

    /**
     * @see shell.command.ShellCommand#execute(java.lang.String,
     *      java.io.PrintStream, java.io.PrintStream).
     */
    public void execute(final String cmdline, final PrintStream out,
	    final PrintStream err) {
	/*
	 * Récupération des arguments
	 */
	List<String> args = Shell.analyserCommande(cmdline);

	Class<?> classe = null;
	try {
	    /*
	     * Recherche de la classe
	     */
	    classe = (Class<?>) Class.forName(args.get(0));
	} catch (final ClassNotFoundException e) {
	    err.println("Classe " + args.get(0) + " non trouvée : "
		    + e.getMessage());
	} catch (final ClassCastException e) {
	    err.println("Erreur lors de la conversion de la classe "
		    + args.get(0) + " : " + e.getMessage());
	}

	/*
	 * Préparation des arguments
	 */
	String[] arguments = new String[args.size() - 1];
	for (int i = 1; i < args.size(); ++i) {
	    arguments[i - 1] = args.get(i);
	}

	try {
	    /*
	     * Appel dynamique
	     */
	    Method main = classe.getMethod("main", String[].class);
	    main.invoke(null, (Object) arguments);
	} catch (final SecurityException e) {
	    err.println(e.getMessage());
	} catch (final NoSuchMethodException e) {
	    err.println("Méthode main non trouvée : " + e.getMessage());
	} catch (final IllegalArgumentException e) {
	    err.println(e.getMessage());
	} catch (final IllegalAccessException e) {
	    err.println(e.getMessage());
	} catch (final InvocationTargetException e) {
	    err.println(e.getMessage());
	}
    }
}
